using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Timers;
using ODT.Common.Core;
using ODT.Common.Services;
using ODT.Licensing;
using ODT.PMACGlobal;
using ODT.PowerPmacComLib;

namespace PPGatherControl
{
	[LicenseProvider(typeof(ReflectingLicenseProvider))]
	public class PPGatherControl
	{
		public delegate void GatherError(object sender, string errormsg, int errorcode);

		public delegate void FileMethodChanged(object sender, bool filegather);

		public delegate void GatherComplete(object sender, string completemsg);

		public delegate void SocketError(object sender, string type, string msg);

		public delegate void GatherProgress(object sender, int count);

		public delegate void GatherDataAvailable(object sender, string data);

		public delegate void ReadyToGather(object sender, string ipAddress);

		public delegate void OutOfMemory(object sender);

		public enum GatherTypes
		{
			Static,
			Streaming
		}

		public enum GatherPeriodTypes
		{
			Servo,
			Phase
		}

		private bool gatherstartstop;

		private GatherTypes gathertype;

		private GatherPeriodTypes gatherperiodtype;

		private List<string> addresslist = new List<string>();

		private int gatherperiod = 10;

		private int gatherenable;

		private int gatheritem;

		private int gathermaxsamples;

		private string ipaddress = string.Empty;

		private int port = 22;

		private string username = string.Empty;

		private string password = string.Empty;

		private CommunicationGlobals.ConnectionTypes connectiontype;

		private ISyncGpasciiCommunicationInterface SyncSSHClient;

		private IAsyncTerminalCommunicationInterface ASyncOSClient;

		private ISyncTerminalCommunicationInterface SyncOSClient;

		private bool Gpasciiloginsuccess;

		private bool OS_Async_loginsuccess;

		private bool OS_Sync_loginsuccess;

		private string gatherstring = string.Empty;

		private string stringtosplit = string.Empty;

		private int gatherdatacounter;

		private string CmdGatherenable = "Gather.{0}Enable";

		private string CmdGatheritems = "Gather.{0}Items";

		private string CmdGatherperiod = "Gather.{0}Period";

		private string CmdGathermaxsamples = "Gather.{0}MaxSamples";

		private const string SERVO = "";

		private const string PHASE = "Phase";

		private Process localNC;

		private List<string> dataList;

		private string _ncport;

		private string _hostip;

		private BackgroundWorker bgworker;

		private bool readytogather;

		private bool _filemethod;

		private bool overtime;

		private bool _lineBuffer;

		private bool _firmware;

		private bool _load;

		private int _gatherport = -1;

		private List<string> _datalist;

		private bool _localdatagathering;

		private long _maxbytes = 1000000000L;

		private int _startlooking = 700000;

		private readonly IApplicationSettingsService applicationSettingsService;

		private readonly ILanguageTranslationService languageTranslationService;

		private string addressErrorFormat;

		private string dataInputErrorFormat;

		private string emptyAddressListText;

		private string gatherFailText;

		private string gatherSamplesErrorText;

		private string restartingConnectionText;

		private string cannotDetermineLocalIpText;

		private string localProgramDidNotStartText;

		private string nonGpasciiConnectionToDeviceText;

		private string cannotDetermineHostIpText;

		private string waitForReadyToGatherEventText;

		private string tooManyGatherItemsFormat;

		private string fileOrDirectoryDoesNotExistFormat;

		private string portInUseFormat;

		private bool asyncStreamingFlag;

		private bool overtimeGBO;

		private System.Timers.Timer filegathertimer;

		private System.Timers.Timer progressbartimer;

		private int gatherprogresscount;

		private int gatherprogressperinterval;

		public bool IsReadyToGather => readytogather;

		public GatherTypes GatherType
		{
			get
			{
				return gathertype;
			}
			set
			{
				gathertype = value;
			}
		}

		public GatherPeriodTypes GatherPeriodType
		{
			get
			{
				return gatherperiodtype;
			}
			set
			{
				if (gatherperiodtype == value)
				{
					return;
				}
				if (!_filemethod)
				{
					readytogather = false;
					if (ASyncOSClient != null && ASyncOSClient.SocketConnected)
					{
						ASyncOSClient.AsyncSendCommand("\u0003");
					}
					if (localNC != null && !localNC.HasExited)
					{
						try
						{
							localNC.Kill();
						}
						catch (Exception)
						{
						}
					}
					gatherperiodtype = value;
					StartNCAndGatherDataProcess();
				}
				else
				{
					gatherperiodtype = value;
				}
			}
		}

		public List<string> AddressList
		{
			get
			{
				return addresslist;
			}
			set
			{
				addresslist = value;
			}
		}

		private int GatherEnable
		{
			get
			{
				return gatherenable;
			}
			set
			{
				gatherenable = value;
			}
		}

		public int GatherPeriod
		{
			get
			{
				return gatherperiod;
			}
			set
			{
				gatherperiod = value;
			}
		}

		private int GatherItem
		{
			get
			{
				return gatheritem;
			}
			set
			{
				gatheritem = value;
			}
		}

		public int GatherMaxSamples
		{
			get
			{
				return gathermaxsamples;
			}
			set
			{
				gathermaxsamples = value;
			}
		}

		public List<string> DatagatherList => _datalist;

		public bool FileMethod
		{
			get
			{
				return _filemethod;
			}
			set
			{
				if (_filemethod != value)
				{
					if (value)
					{
						if (ASyncOSClient != null && ASyncOSClient.SocketConnected)
						{
							ASyncOSClient.AsyncSendCommand("\u0003");
							if (localNC != null && !localNC.HasExited)
							{
								try
								{
									localNC.Kill();
								}
								catch (Exception)
								{
								}
							}
						}
						readytogather = true;
						if (this.ReadyToGatherEvent != null)
						{
							this.ReadyToGatherEvent(this, ipaddress);
						}
					}
					else if (ASyncOSClient != null && ASyncOSClient.SocketConnected)
					{
						readytogather = false;
						bgworker = new BackgroundWorker();
						bgworker.DoWork -= bgworker_DoWork;
						bgworker.DoWork += bgworker_DoWork;
						bgworker.RunWorkerAsync();
					}
					_filemethod = value;
					if (this.FileMethodChangedEvent != null)
					{
						this.FileMethodChangedEvent(this, value);
					}
				}
				_filemethod = value;
			}
		}

		public bool Firmware => _firmware;

		public int GatherPort
		{
			get
			{
				return _gatherport;
			}
			set
			{
				_gatherport = value;
			}
		}

		public bool LineBuffer
		{
			get
			{
				return _lineBuffer;
			}
			set
			{
				if ((_lineBuffer && value) || (!_lineBuffer && !value) || FileMethod)
				{
					_lineBuffer = value;
					return;
				}
				if (ASyncOSClient != null && ASyncOSClient.SocketConnected)
				{
					ASyncOSClient.AsyncSendCommand("\u0003");
				}
				if (localNC != null && !localNC.HasExited)
				{
					try
					{
						localNC.Kill();
					}
					catch (Exception)
					{
					}
				}
				readytogather = false;
				_lineBuffer = value;
				StartNCAndGatherDataProcess();
			}
		}

		public event GatherError GatherErrorEvent;

		public event FileMethodChanged FileMethodChangedEvent;

		public event GatherComplete GatherCompleteEvent;

		public event SocketError SocketErrorEvent;

		public event GatherProgress GatherProgressEvent;

		public event GatherDataAvailable GatherDataAvailableEvent;

		public event ReadyToGather ReadyToGatherEvent;

		public event OutOfMemory OutOfMemoryEvent;

		public PPGatherControl()
		{
			applicationSettingsService = ServiceManager.GetService<IApplicationSettingsService>();
			languageTranslationService = ServiceManager.GetService<ILanguageTranslationService>();
			SetLanguageTranslations();
			connectiontype = CommunicationGlobals.ConnectionTypes.SSH;
			ASyncOSClient = new AsyncDTCommunication();
			SyncSSHClient = new DTCommunication();
			SyncOSClient = new TelnetTerminal();
			bgworker = new BackgroundWorker();
			bgworker.DoWork -= bgworker_DoWork;
			bgworker.DoWork += bgworker_DoWork;
		}

		public PPGatherControl(long MaxBytesUsedBeforeOutOfMem, int ItemsBeforeMemCheck)
			: this()
		{
			_maxbytes = MaxBytesUsedBeforeOutOfMem;
			_startlooking = ItemsBeforeMemCheck;
		}

		private void SetLanguageTranslations()
		{
			addressErrorFormat = languageTranslationService.Translate("PPGather.AddressErrorFormat");
			dataInputErrorFormat = languageTranslationService.Translate("PPGather.DataInputErrorFormat");
			emptyAddressListText = languageTranslationService.Translate("PPGather.EmptyAddressListText");
			gatherFailText = languageTranslationService.Translate("PPGather.GatherFailText");
			gatherSamplesErrorText = languageTranslationService.Translate("PPGather.GatherSamplesErrorText");
			restartingConnectionText = languageTranslationService.Translate("PPGather.RestartingConnectionText");
			cannotDetermineLocalIpText = languageTranslationService.Translate("PPGather.CannotDetermineLocalIpText");
			localProgramDidNotStartText = languageTranslationService.Translate("PPGather.LocalProgramDidNotStartText");
			nonGpasciiConnectionToDeviceText = languageTranslationService.Translate("PPGather.NonGpasciiConnectionToDeviceText");
			cannotDetermineHostIpText = languageTranslationService.Translate("PPGather.CannotDetermineHostIpText");
			waitForReadyToGatherEventText = languageTranslationService.Translate("PPGather.WaitForReadyToGatherEventText");
			tooManyGatherItemsFormat = languageTranslationService.Translate("PPGather.TooManyGatherItemsFormat");
			fileOrDirectoryDoesNotExistFormat = languageTranslationService.Translate("PPGather.FileOrDirectoryDoesNotExistFormat");
			portInUseFormat = languageTranslationService.Translate("PPGather.PortInUseFormat");
		}

		~PPGatherControl()
		{
			DisconnectFromDevice();
		}

		public bool ConnectToDevice(string IpAddress, string Username, string Password, int Port)
		{
			bool result = false;
			ipaddress = IpAddress;
			username = Username;
			password = Password;
			port = Port;
			CheckConnectionExist();
			Gpasciiloginsuccess = SyncSSHClient.ConnectGpAscii(ipaddress, port, username, password);
			if (Gpasciiloginsuccess)
			{
				SyncSSHClient.ComERROR += SyncSSHClient_ComERROR;
				string response;
				SyncSSHClient.GetResponse("Gather.Enable=0 Gather.PhaseEnable=0 vers", out response);
				bool flag = IDEGlobals.CheckVersion("2.0.2.63", response.Trim());
				if (flag)
				{
					_firmware = true;
				}
				FileMethod = flag;
				OS_Async_loginsuccess = ASyncOSClient.ConnectTerminal(ipaddress, port, username, password);
				if (!OS_Async_loginsuccess)
				{
					return result;
				}
				ASyncOSClient.ComERROR -= ASyncOSClient_ComERROR;
				ASyncOSClient.ComERROR += ASyncOSClient_ComERROR;
				if (!_filemethod)
				{
					bgworker = new BackgroundWorker();
					bgworker.DoWork -= bgworker_DoWork;
					bgworker.DoWork += bgworker_DoWork;
					bgworker.RunWorkerAsync();
				}
				else
				{
					readytogather = true;
					if (this.ReadyToGatherEvent != null)
					{
						this.ReadyToGatherEvent(this, ipaddress);
					}
				}
				return true;
			}
			return result;
		}

		private void bgworker_DoWork(object sender, DoWorkEventArgs e)
		{
			_hostip = GetHostIP();
			StartNCAndGatherDataProcess();
		}

		private void StartNCAndGatherDataProcess()
		{
			if (StartNCProcess())
			{
				Thread.Sleep(500);
				StartGatherDataProcessOnPowerPMAC();
			}
		}

		private bool StartNCProcess()
		{
			if (localNC != null && !localNC.HasExited)
			{
				try
				{
					localNC.Kill();
				}
				catch (Exception)
				{
				}
			}
			Random random = new Random();
			if (_gatherport == -1)
			{
				_ncport = random.Next(19001, 20000).ToString();
			}
			else
			{
				_ncport = _gatherport.ToString();
			}
			ProcessStartInfo processStartInfo = new ProcessStartInfo();
			processStartInfo.FileName = "DeltaTauGatherProgram.exe";
			processStartInfo.Arguments = "-v -n -l -p " + _ncport;
			processStartInfo.CreateNoWindow = true;
			processStartInfo.RedirectStandardOutput = true;
			processStartInfo.RedirectStandardError = true;
			processStartInfo.UseShellExecute = false;
			processStartInfo.WorkingDirectory = GetCompilePath() + "\\rsync";
			processStartInfo.FileName = Path.Combine(GetPlotControlPath(), processStartInfo.FileName);
			if (!File.Exists(processStartInfo.FileName))
			{
				SendGatherError(string.Format(fileOrDirectoryDoesNotExistFormat, Path.GetFileName(processStartInfo.FileName), Path.GetDirectoryName(processStartInfo.FileName)), 12);
				return false;
			}
			if (!File.Exists(processStartInfo.WorkingDirectory + "\\cygwin1.dll"))
			{
				SendGatherError(string.Format(fileOrDirectoryDoesNotExistFormat, "cygwin1.dll", processStartInfo.WorkingDirectory), 12);
				return false;
			}
			localNC = Process.Start(processStartInfo);
			if (localNC != null)
			{
				dataList = new List<string>(100000);
				gatherdatacounter = 0;
				localNC.OutputDataReceived -= localNC_OutputDataReceived;
				localNC.OutputDataReceived += localNC_OutputDataReceived;
				localNC.ErrorDataReceived -= localNC_ErrorDataReceived;
				localNC.ErrorDataReceived += localNC_ErrorDataReceived;
				localNC.BeginOutputReadLine();
				localNC.BeginErrorReadLine();
				int num = 0;
				while (num < 10)
				{
					num++;
					if (Process.GetProcesses().Any((Process x) => x.Id == localNC.Id))
					{
						break;
					}
					Thread.Sleep(1000);
				}
				if (num < 10)
				{
					return true;
				}
			}
			SendGatherError(localProgramDidNotStartText, 13);
			return false;
		}

		private string GetCompilePath()
		{
			if (!Directory.Exists(applicationSettingsService.CompilerPath))
            {
				return System.AppDomain.CurrentDomain.BaseDirectory + "\\tool\\Compilers\\";
			}

			return applicationSettingsService.CompilerPath;
		}

		private string GetPlotControlPath()
        {
			if (!Directory.Exists(applicationSettingsService.PlotControlPath))
			{
				return System.AppDomain.CurrentDomain.BaseDirectory + "\\tool\\PlotControl\\";
			}

			return applicationSettingsService.PlotControlPath;
		}

		private void StartGatherDataProcessOnPowerPMAC()
		{
			if (ASyncOSClient != null && ASyncOSClient.SocketConnected)
			{
				ASyncOSClient.ComERROR -= ASyncOSClient_ComERROR;
				ASyncOSClient.ComERROR += ASyncOSClient_ComERROR;
				bool flag = false;
				if (string.IsNullOrEmpty(_hostip))
				{
					_hostip = GetHostIP();
					flag = true;
				}
				if (_hostip != null && _hostip != string.Empty)
				{
					if (!FileMethod)
					{
						ASyncOSClient.AsyncSendCommand("\u0003");
						if (_lineBuffer)
						{
							if (gatherperiodtype == GatherPeriodTypes.Servo)
							{
								ASyncOSClient.AsyncSendCommand("stdbuf -oL gather -W | nc -v -n " + _hostip + " " + _ncport);
							}
							else
							{
								ASyncOSClient.AsyncSendCommand("stdbuf -oL gather -p -W | nc -v -n " + _hostip + " " + _ncport);
							}
						}
						else if (gatherperiodtype == GatherPeriodTypes.Servo)
						{
							ASyncOSClient.AsyncSendCommand("gather -W | nc -v -n " + _hostip + " " + _ncport);
						}
						else
						{
							ASyncOSClient.AsyncSendCommand("gather -p -W | nc -v -n " + _hostip + " " + _ncport);
						}
					}
					else
					{
						if (!flag)
						{
							_hostip = GetHostIP();
						}
						ASyncOSClient.AsyncSendCommand("echo -e \"\\nendoffile\\n\" | cat /var/ftp/gather/GatherFile.txt - | nc -v -n " + _hostip + " " + _ncport);
					}
				}
				else
				{
					try
					{
						localNC.Kill();
					}
					catch (Exception)
					{
					}
					SendGatherError(cannotDetermineHostIpText, 11);
				}
			}
			else
			{
				SendGatherError(nonGpasciiConnectionToDeviceText, 13);
			}
		}

		private void StartGatherDataProcessOnPowerPMACLegacyStreaming()
		{
			if (ASyncOSClient == null || !ASyncOSClient.SocketConnected)
			{
				return;
			}
			ASyncOSClient.ComERROR -= ASyncOSClient_ComERROR;
			ASyncOSClient.ComERROR += ASyncOSClient_ComERROR;
			if (_hostip != string.Empty)
			{
				ASyncOSClient.AsyncSendCommand("\u0003");
				if (!_lineBuffer)
				{
					if (gatherperiodtype == GatherPeriodTypes.Servo)
					{
						ASyncOSClient.AsyncSendCommand("gather | nc -v -n " + _hostip + " " + _ncport);
					}
					else
					{
						ASyncOSClient.AsyncSendCommand("gather -p | nc -v -n " + _hostip + " " + _ncport);
					}
				}
				else if (gatherperiodtype == GatherPeriodTypes.Servo)
				{
					asyncStreamingFlag = true;
					ASyncOSClient.AsyncDataAvailable -= ASyncOSClient_AsyncDataAvailable;
					ASyncOSClient.AsyncDataAvailable += ASyncOSClient_AsyncDataAvailable;
					ASyncOSClient.AsyncSendCommand("gather");
				}
				else
				{
					asyncStreamingFlag = true;
					ASyncOSClient.AsyncDataAvailable -= ASyncOSClient_AsyncDataAvailable;
					ASyncOSClient.AsyncDataAvailable += ASyncOSClient_AsyncDataAvailable;
					ASyncOSClient.AsyncSendCommand("gather -p");
				}
			}
			else
			{
				try
				{
					localNC.Kill();
				}
				catch (Exception)
				{
				}
				SendGatherError(cannotDetermineHostIpText, 11);
			}
		}

		private IPAddress GetHostIP()
		{
			string response;
			SyncSSHClient.GetResponse("system echo $SSH_CLIENT | awk '{ print $1}'", out response);
			string[] array = response.Split(new char[1] { '\n' }, StringSplitOptions.RemoveEmptyEntries);
			IPAddress iPAddress = null;
			if (array.Length != 0)
			{
				iPAddress = new IPAddress(array[0]);
			}
			if (string.IsNullOrEmpty(iPAddress) || !iPAddress.IsValidAddress)
			{
				SendGatherError(cannotDetermineLocalIpText, 11);
			}
			return iPAddress;
		}

		private bool CheckIPConnectionToPowerPMAC(string IpV4Address)
		{
			ProcessStartInfo processStartInfo = new ProcessStartInfo();
			processStartInfo.FileName = "cmd.exe";
			processStartInfo.Arguments = "/C Ping -w 1000 -n 2 -S " + IpV4Address + " " + ipaddress;
			processStartInfo.UseShellExecute = false;
			processStartInfo.ErrorDialog = true;
			processStartInfo.RedirectStandardOutput = true;
			processStartInfo.CreateNoWindow = true;
			Process process = new Process();
			process.StartInfo = processStartInfo;
			process.Start();
			process.WaitForExit();
			string[] array = process.StandardOutput.ReadToEnd().Split(new char[2] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
			for (int i = 0; i < array.Length; i++)
			{
				if (array[i].Contains(" Lost = 0 (0% loss)"))
				{
					return true;
				}
			}
			return false;
		}

		private void CheckConnectionExist()
		{
			if (ASyncOSClient != null)
			{
				if (ASyncOSClient.SocketConnected)
				{
					ASyncOSClient.DisconnectTerminal();
				}
				ASyncOSClient.ComERROR -= ASyncOSClient_ComERROR;
			}
			if (SyncSSHClient != null)
			{
				if (SyncSSHClient.GpAsciiConnected)
				{
					SyncSSHClient.DisconnectGpascii();
				}
				SyncSSHClient.ComERROR -= SyncSSHClient_ComERROR;
			}
		}

		public void DisconnectFromDevice()
		{
			try
			{
				if (SyncSSHClient != null && SyncSSHClient.GpAsciiConnected)
				{
					SyncSSHClient.DisconnectGpascii();
					SyncSSHClient.ComERROR -= SyncSSHClient_ComERROR;
				}
				if (ASyncOSClient != null && ASyncOSClient.SocketConnected)
				{
					ASyncOSClient.AsyncSendCommand("\u0003");
					ASyncOSClient.DisconnectTerminal();
					ASyncOSClient.ComERROR -= ASyncOSClient_ComERROR;
				}
				if (localNC != null && !localNC.HasExited)
				{
					try
					{
						localNC.Kill();
						return;
					}
					catch (Exception)
					{
						return;
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void localNC_ErrorDataReceived(object sender, DataReceivedEventArgs e)
		{
			if (e.Data == null)
			{
				return;
			}
			if (e.Data.Contains("connect to [" + _hostip))
			{
				readytogather = true;
			}
			else
			{
				if (!e.Data.Contains("Address already in use"))
				{
					return;
				}
				readytogather = false;
				try
				{
					localNC.Kill();
				}
				catch (Exception)
				{
				}
				ASyncOSClient.AsyncSendCommand("\u0003");
				if (this.GatherErrorEvent != null)
				{
					if (_gatherport == -1)
					{
						SendGatherError(string.Format(portInUseFormat, _ncport), 1);
						StartNCAndGatherDataProcess();
					}
					else
					{
						SendGatherError(string.Format(portInUseFormat, _ncport), 1);
					}
				}
			}
		}

		private void localNC_OutputDataReceived(object sender, DataReceivedEventArgs e)
		{
			if (e.Data == null || !(e.Data != string.Empty))
			{
				return;
			}
			if (GatherType == GatherTypes.Static)
			{
				if (FileMethod)
				{
					if (e.Data.StartsWith("endoffile", StringComparison.Ordinal))
					{
						gatherdatacounter++;
						_datalist = new List<string>(dataList);
						dataList.Clear();
						ASyncOSClient.AsyncSendCommand("\u0003");
						if (this.GatherCompleteEvent != null)
						{
							this.GatherCompleteEvent(this, "Data gather complete");
						}
						readytogather = true;
						if (this.ReadyToGatherEvent != null)
						{
							this.ReadyToGatherEvent(this, ipaddress);
						}
					}
					else
					{
						dataList.Add(e.Data);
						gatherdatacounter++;
						if (this.GatherProgressEvent != null)
						{
							this.GatherProgressEvent(this, gatherdatacounter);
						}
					}
				}
				else if (overtime)
				{
					if (e.Data.Contains("Gather buffer overrun"))
					{
						readytogather = false;
						overtimeGBO = true;
						dataList.Clear();
						overtime = false;
						try
						{
							localNC.Kill();
						}
						catch (Exception)
						{
						}
						ASyncOSClient.AsyncSendCommand("\u0003");
						StartNCAndGatherDataProcess();
					}
					else if (e.Data.Contains("Waiting"))
					{
						dataList.Clear();
						overtime = false;
						readytogather = true;
						if (this.ReadyToGatherEvent != null)
						{
							this.ReadyToGatherEvent(this, ipaddress);
						}
					}
				}
				else if (!e.Data.Contains("Gather buffer overrun"))
				{
					if (!e.Data.StartsWith("Waiting", StringComparison.Ordinal))
					{
						try
						{
							if (dataList.Count > _startlooking && GC.GetTotalMemory(false) > _maxbytes)
							{
								throw new OutOfMemoryException();
							}
							dataList.Add(e.Data);
							gatherdatacounter++;
							if (this.GatherProgressEvent != null)
							{
								this.GatherProgressEvent(this, gatherdatacounter);
							}
							return;
						}
						catch (OutOfMemoryException)
						{
							this.OutOfMemoryEvent(this);
							dataList.Clear();
							GC.Collect();
							return;
						}
					}
					StopGather();
					overtimeGBO = false;
					overtime = false;
					dataList.Clear();
					readytogather = true;
					if (this.ReadyToGatherEvent != null)
					{
						this.ReadyToGatherEvent(this, ipaddress);
					}
				}
				else
				{
					StopGather();
					readytogather = false;
					try
					{
						localNC.Kill();
					}
					catch (Exception)
					{
					}
					ASyncOSClient.AsyncSendCommand("\u0003");
					SendGatherError(e.Data, 0);
					StartNCAndGatherDataProcess();
				}
			}
			else if (overtime)
			{
				if (e.Data.Contains("Gather buffer overrun"))
				{
					dataList.Clear();
					overtime = false;
					readytogather = false;
					try
					{
						localNC.Kill();
					}
					catch (Exception)
					{
					}
					ASyncOSClient.AsyncSendCommand("\u0003");
					StartNCAndGatherDataProcess();
				}
				else if (e.Data.Contains("Waiting"))
				{
					dataList.Clear();
					overtime = false;
					readytogather = true;
					if (this.ReadyToGatherEvent != null)
					{
						this.ReadyToGatherEvent(this, ipaddress);
					}
				}
			}
			else if (!e.Data.StartsWith("Gather buffer overrun", StringComparison.Ordinal))
			{
				if (e.Data.StartsWith("Waiting", StringComparison.Ordinal))
				{
					StopGather();
					overtime = false;
					dataList.Clear();
					readytogather = true;
					if (this.ReadyToGatherEvent != null)
					{
						this.ReadyToGatherEvent(this, ipaddress);
					}
				}
				else if (this.GatherDataAvailableEvent != null)
				{
					this.GatherDataAvailableEvent(this, e.Data);
				}
			}
			else
			{
				StopGather();
				readytogather = false;
				try
				{
					localNC.Kill();
				}
				catch (Exception)
				{
				}
				ASyncOSClient.AsyncSendCommand("\u0003");
				SendGatherError(e.Data, 0);
				StartNCAndGatherDataProcess();
			}
		}

		private void SyncSSHClient_ComERROR(object sender, ComErArgs e)
		{
			if (this.SocketErrorEvent != null)
			{
				this.SocketErrorEvent(this, "Sync", e.ErrorMessage);
			}
		}

		private void ASyncOSClient_AsyncDataAvailable(object sender, AsyncDataArgs e)
		{
			try
			{
				char[] separator = new char[1] { '\n' };
				lock (this)
				{
					gatherstring += e.Response;
					gatherstring.LastIndexOf('\n');
					stringtosplit = gatherstring.Substring(0, gatherstring.Length - (gatherstring.Length - gatherstring.LastIndexOf('\n')) + 1);
					gatherstring = gatherstring.Remove(0, gatherstring.Length - (gatherstring.Length - gatherstring.LastIndexOf('\n')) + 1);
					string[] array = stringtosplit.Split(separator);
					foreach (string text in array)
					{
						if (!string.IsNullOrEmpty(text) && this.GatherDataAvailableEvent != null)
						{
							this.GatherDataAvailableEvent(this, text);
						}
					}
				}
			}
			catch (Exception)
			{
			}
		}

		private void ASyncOSClient_ComERROR(object sender, ComErArgs e)
		{
			if (this.SocketErrorEvent != null)
			{
				this.SocketErrorEvent(this, "Async", e.ErrorMessage);
			}
		}

		public void StartGather()
		{
			if ((localNC == null || localNC.HasExited) && !_filemethod)
			{
				SendGatherError(restartingConnectionText, 3);
				StartNCAndGatherDataProcess();
				return;
			}
			if (!readytogather)
			{
				SendGatherError(waitForReadyToGatherEventText, 4);
				return;
			}
			if (overtime)
			{
				overtime = false;
			}
			dataList = new List<string>(100000);
			gatherdatacounter = 0;
			gatherstring = string.Empty;
			_datalist = new List<string>();
			_localdatagathering = true;
			if (!SendGatherSettingsToPowerPMAC())
			{
				_localdatagathering = false;
				SendGatherError(gatherFailText, 5);
			}
			else
			{
				readytogather = false;
			}
		}

		private bool SendGatherSettingsToPowerPMAC()
		{
			string response = string.Empty;
			List<string> response2 = new List<string>();
			string empty = string.Empty;
			string arg = "";
			if (GatherPeriodType == GatherPeriodTypes.Phase)
			{
				arg = "Phase";
			}
			string text = string.Format(CmdGatherenable, arg);
			SyncSSHClient.GetResponse(text + " = 0", out response);
			if (!CheckInputdataValidity(response))
			{
				empty = string.Format(dataInputErrorFormat, text + " = 0", response);
				SendGatherError(empty, 6);
				return false;
			}
			if (!ValidateAddressList())
			{
				return false;
			}
			SyncSSHClient.GetResponse(AddressList, out response2);
			int num = CheckInputdataValidity(response2);
			if (num != -1)
			{
				empty = string.Format(dataInputErrorFormat, AddressList[num], response2[num]);
				SendGatherError(empty, 6);
				return false;
			}
			int num2 = ((GatherPeriodType != 0) ? 8 : 128);
			if (AddressList.Count > num2)
			{
				SendGatherError(string.Format(tooManyGatherItemsFormat, num2), 6);
				return false;
			}
			for (int i = 0; i < AddressList.Count; i++)
			{
				if (GatherPeriodType == GatherPeriodTypes.Servo)
				{
					SyncSSHClient.GetResponse("Gather.Addr[" + i + "]=" + AddressList[i], out response);
				}
				else
				{
					SyncSSHClient.GetResponse("Gather.PhaseAddr[" + i + "]=" + AddressList[i], out response);
				}
			}
			text = string.Format(CmdGatherperiod, arg);
			SyncSSHClient.GetResponse(text + " = " + GatherPeriod, out response);
			if (!CheckInputdataValidity(response))
			{
				empty = string.Format(dataInputErrorFormat, text + " = " + GatherPeriod, response);
				SendGatherError(empty, 6);
				return false;
			}
			if (AddressList.Count > 0)
			{
				text = string.Format(CmdGatheritems, arg);
				SyncSSHClient.GetResponse(text + " = " + AddressList.Count, out response);
				if (!CheckInputdataValidity(response))
				{
					empty = string.Format(dataInputErrorFormat, text + " = " + AddressList.Count, response);
					SendGatherError(empty, 6);
					return false;
				}
				if (GatherType == GatherTypes.Static && GatherMaxSamples <= 0)
				{
					SendGatherError(gatherSamplesErrorText, 8);
					return false;
				}
				text = string.Format(CmdGathermaxsamples, arg);
				SyncSSHClient.GetResponse(text + " = " + GatherMaxSamples, out response);
				if (!CheckInputdataValidity(response))
				{
					empty = string.Format(dataInputErrorFormat, text + " = " + GatherMaxSamples, response);
					SendGatherError(empty, 6);
					return false;
				}
				if (!_filemethod)
				{
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 1", out response);
					if (response.Contains("Struct Write Error"))
					{
						return false;
					}
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 0", out response);
					if (GatherType == GatherTypes.Streaming)
					{
						text = string.Format(CmdGatherenable, arg);
						SyncSSHClient.GetResponse(text + " = 3", out response);
					}
					else
					{
						text = string.Format(CmdGatherenable, arg);
						SyncSSHClient.GetResponse(text + " = 2", out response);
					}
				}
				else if (GatherType == GatherTypes.Static)
				{
					filegathertimer = new System.Timers.Timer();
					filegathertimer.Elapsed -= filegathertimer_Elapsed;
					filegathertimer.Elapsed += filegathertimer_Elapsed;
					progressbartimer = new System.Timers.Timer();
					progressbartimer.Elapsed -= progressbartimer_Elapsed;
					progressbartimer.Elapsed += progressbartimer_Elapsed;
					SyncSSHClient.GetResponse("Sys.ServoPeriod", out response);
					if (response == string.Empty)
					{
						return false;
					}
					string value = response.Substring(16, response.Length - 16);
					filegathertimer.Interval = Convert.ToDouble(value);
					if (GatherPeriodType == GatherPeriodTypes.Phase)
					{
						SyncSSHClient.GetResponse("Sys.PhaseOverServoPeriod", out response);
						if (response == string.Empty)
						{
							return false;
						}
						value = response.Substring(25, response.Length - 25);
						filegathertimer.Interval *= Convert.ToDouble(value);
					}
					filegathertimer.Interval = filegathertimer.Interval * (double)GatherPeriod * (double)GatherMaxSamples;
					filegathertimer.Interval += 200.0;
					filegathertimer.AutoReset = false;
					progressbartimer.Interval = filegathertimer.Interval / 100.0;
					progressbartimer.AutoReset = true;
					gatherprogresscount = 0;
					gatherprogressperinterval = GatherMaxSamples / 100;
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 1", out response);
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 0", out response);
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 2", out response);
					filegathertimer.Start();
					progressbartimer.Start();
				}
				else if (GatherType == GatherTypes.Streaming)
				{
					_hostip = GetHostIP();
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 1", out response);
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 0", out response);
					text = string.Format(CmdGatherenable, arg);
					SyncSSHClient.GetResponse(text + " = 3", out response);
					if (!_lineBuffer)
					{
						StartNCProcess();
						Thread.Sleep(500);
					}
					StartGatherDataProcessOnPowerPMACLegacyStreaming();
				}
				return true;
			}
			SendGatherError(emptyAddressListText, 7);
			return false;
		}

		private void progressbartimer_Elapsed(object sender, ElapsedEventArgs e)
		{
			gatherprogresscount += gatherprogressperinterval;
			if (this.GatherProgressEvent != null)
			{
				this.GatherProgressEvent(this, gatherprogresscount);
			}
			if (gatherprogressperinterval * 100 == gatherprogresscount)
			{
				progressbartimer.Stop();
			}
		}

		private void filegathertimer_Elapsed(object sender, ElapsedEventArgs e)
		{
			if (progressbartimer != null)
			{
				progressbartimer.Stop();
			}
			if (this.GatherProgressEvent != null)
			{
				this.GatherProgressEvent(this, gathermaxsamples);
			}
			if (this.GatherCompleteEvent != null)
			{
				this.GatherCompleteEvent(this, "Data gather complete");
			}
			readytogather = true;
			if (this.ReadyToGatherEvent != null)
			{
				this.ReadyToGatherEvent(this, ipaddress);
			}
		}

		public bool UploadFileGatherFileMethod()
		{
			if (_filemethod)
			{
				string arg = "";
				if (GatherPeriodType == GatherPeriodTypes.Phase)
				{
					arg = "Phase";
				}
				string text = $"Gather.{arg}Enable";
				string response;
				SyncSSHClient.GetResponse("Gather.Enable", out response);
				if (response == string.Empty)
				{
					return false;
				}
				int num = response.IndexOf('=');
				if (Convert.ToInt32(response.Substring(num + 1, response.Length - (num + 1))) == 0)
				{
					if (ASyncOSClient.SocketConnected)
					{
						readytogather = false;
						ASyncOSClient.AsyncDataAvailable -= ASyncOSClient_AsyncDataAvailableGatherFile;
						ASyncOSClient.AsyncDataAvailable += ASyncOSClient_AsyncDataAvailableGatherFile;
						if (GatherPeriodType == GatherPeriodTypes.Phase)
						{
							ASyncOSClient.AsyncSendCommand("gather -p -u /var/ftp/gather/GatherFile.txt");
						}
						else
						{
							ASyncOSClient.AsyncSendCommand("gather -u /var/ftp/gather/GatherFile.txt");
						}
						return true;
					}
					return false;
				}
				return false;
			}
			return false;
		}

		private void ASyncOSClient_AsyncDataAvailableGatherFile(object sender, AsyncDataArgs e)
		{
			if (e.Response.Contains(username + "@" + ipaddress))
			{
				StartNCProcess();
				ASyncOSClient.AsyncDataAvailable -= ASyncOSClient_AsyncDataAvailableGatherFile;
				gatherdatacounter = 0;
				gatherstring = string.Empty;
				Thread.Sleep(500);
				StartGatherDataProcessOnPowerPMAC();
			}
		}

		private bool ValidateAddressList()
		{
			int num = 0;
			if (GatherPeriodType == GatherPeriodTypes.Phase)
			{
				foreach (string address in AddressList)
				{
					if (address.ToLower().Contains("phase"))
					{
						num++;
					}
				}
				if (AddressList.Count < num)
				{
					SendGatherError(string.Format(addressErrorFormat, GatherPeriodType), 10);
					return false;
				}
			}
			return true;
		}

		public void StopGather()
		{
			if (filegathertimer != null)
			{
				filegathertimer.Elapsed -= filegathertimer_Elapsed;
				filegathertimer.Stop();
			}
			if (progressbartimer != null)
			{
				progressbartimer.Elapsed -= progressbartimer_Elapsed;
				progressbartimer.Stop();
			}
			string arg = "";
			string response = string.Empty;
			_localdatagathering = false;
			if (GatherPeriodType == GatherPeriodTypes.Phase)
			{
				arg = "Phase";
			}
			if (SyncSSHClient == null || !SyncSSHClient.GpAsciiConnected)
			{
				return;
			}
			string text = string.Format(CmdGatherenable, arg);
			SyncSSHClient.GetResponse(text + " = 0", out response);
			if (!CheckInputdataValidity(response))
			{
				SendGatherError(string.Format(dataInputErrorFormat, text + " = 0", response), 6);
				return;
			}
			overtime = true;
			if (asyncStreamingFlag)
			{
				ASyncOSClient.AsyncDataAvailable -= ASyncOSClient_AsyncDataAvailable;
			}
			if (GatherType == GatherTypes.Static && !overtimeGBO)
			{
				if (dataList != null)
				{
					_datalist = new List<string>(dataList);
				}
				else
				{
					_datalist = new List<string>();
				}
				dataList = new List<string>();
			}
			gatherdatacounter = 0;
			if (this.GatherCompleteEvent != null)
			{
				this.GatherCompleteEvent(this, "Data gather complete");
			}
			if (_filemethod)
			{
				overtime = false;
				readytogather = true;
				if (this.ReadyToGatherEvent != null)
				{
					this.ReadyToGatherEvent(this, ipaddress);
				}
			}
		}

		public void StopGatherWithRespectToTime()
		{
			if (filegathertimer != null)
			{
				filegathertimer.Elapsed -= filegathertimer_Elapsed;
				filegathertimer.Stop();
			}
			if (progressbartimer != null)
			{
				progressbartimer.Elapsed -= progressbartimer_Elapsed;
				progressbartimer.Stop();
			}
			string arg = "";
			string response = string.Empty;
			if (GatherPeriodType == GatherPeriodTypes.Phase)
			{
				arg = "Phase";
			}
			string text = string.Format(CmdGatherenable, arg);
			SyncSSHClient.GetResponse(text + " = 0", out response);
			if (!CheckInputdataValidity(response))
			{
				SendGatherError(string.Format(dataInputErrorFormat, text + " = 0", response), 6);
			}
			else if (_filemethod)
			{
				readytogather = true;
				if (this.ReadyToGatherEvent != null)
				{
					this.ReadyToGatherEvent(this, ipaddress);
				}
			}
		}

		private bool CheckInputdataValidity(string txt)
		{
			if (IDEGlobals.ExactMatch(txt.ToLower(), "stdin"))
			{
				return false;
			}
			return true;
		}

		private int CheckInputdataValidity(List<string> txtlist)
		{
			for (int i = 0; i < txtlist.Count; i++)
			{
				if (IDEGlobals.ExactMatch(txtlist[i].ToLower(), "stdin"))
				{
					return i;
				}
			}
			return -1;
		}

		private void SendGatherError(string msg, int errorcode)
		{
			this.GatherErrorEvent?.Invoke(this, msg, errorcode);
		}

		public void CleargatherList()
		{
			DatagatherList.Clear();
		}
	}
}
